package com.gaodun.hk.common.config;

import com.alibaba.fastjson.PropertyNamingStrategy;
import com.alibaba.fastjson.parser.Feature;
import com.alibaba.fastjson.parser.ParserConfig;
import com.alibaba.fastjson.serializer.SerializeConfig;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.alibaba.fastjson.support.config.FastJsonConfig;
import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

import java.nio.charset.Charset;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.TimeZone;

/**
 * @author fengyamin
 * @date 2020/04/14
 **/
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {

    /**
     * 时区
     */
    @Value("${fastjson.time-zone:GMT+8}")
    private String timeZone;

    /**
     * 时间格式
     */
    @Value("${fastjson.date-format:yyyy-MM-dd HH:mm:ss}")
    private String dateFormat;

    /**
     * 字符编码
     */
    @Value("${spring.http.encoding.charset:UTF-8}")
    private String charset;

    @Bean
    @Primary
    public ObjectMapper objectMapper() {
        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
        objectMapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
        return objectMapper;
    }

    @Override
    public void addCorsMappings(CorsRegistry registry) {
        LoggerFactory.getLogger(WebMvcConfig.class).debug("add cors");
        registry.addMapping("/**")
                .allowedOrigins("*")
                .allowedMethods("HEAD", "OPTIONS", "GET", "POST", "PUT", "PATCH", "DELETE")
                .maxAge(3600);
    }

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler(new String[]{"/static/**"}).addResourceLocations(new String[]{"classpath:/static/"});
        registry.addResourceHandler(new String[]{"swagger-ui.html"}).addResourceLocations(new String[]{"classpath:/META-INF/resources/"});
        registry.addResourceHandler(new String[]{"/webjars/**"}).addResourceLocations(new String[]{"classpath:/META-INF/resources/webjars/"});
    }

    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
        registry.addViewController("/").setViewName("redirect:/swagger-ui.html");
    }


    @Override
    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
        converters.add(0, fastJsonHttpMessageConverters());
    }

    @Bean
    public HttpMessageConverter fastJsonHttpMessageConverters() {
        FastJsonHttpMessageConverter fastConverter = new FastJsonHttpMessageConverter();
        FastJsonConfig jsonConfig = new FastJsonConfig();
        //设置时区
        TimeZone.setDefault(TimeZone.getTimeZone(timeZone));
        //日期格式
        jsonConfig.setDateFormat(dateFormat);
        //特性设置
        jsonConfig.setFeatures(
                Feature.OrderedField,
                Feature.IgnoreNotMatch
        );
        jsonConfig.setSerializerFeatures(
                SerializerFeature.PrettyFormat,
                SerializerFeature.WriteBigDecimalAsPlain,
                SerializerFeature.WriteDateUseDateFormat,
                SerializerFeature.WriteMapNullValue,
                SerializerFeature.WriteEnumUsingToString,
                SerializerFeature.DisableCircularReferenceDetect
        );
        //字符编码
        jsonConfig.setCharset(Charset.forName(charset));
        //序列化设置
        SerializeConfig serializeConfig = SerializeConfig.globalInstance;
        serializeConfig.propertyNamingStrategy = PropertyNamingStrategy.CamelCase;
        jsonConfig.setSerializeConfig(serializeConfig);
        //反序列化设置
        ParserConfig parserConfig = ParserConfig.getGlobalInstance();
        parserConfig.propertyNamingStrategy = PropertyNamingStrategy.CamelCase;
        //"autoType is not support"问题,使用setAutoTypeSupport=true的全局设置
        parserConfig.setAutoTypeSupport(true);
        jsonConfig.setParserConfig(parserConfig);

        //处理中文乱码
        ArrayList<MediaType> fastMediaTypes = new ArrayList<>();
        fastMediaTypes.add(MediaType.APPLICATION_JSON);
        fastMediaTypes.add(MediaType.APPLICATION_JSON_UTF8);
        fastMediaTypes.add(MediaType.valueOf("text/json;charset=UTF-8"));
        fastConverter.setSupportedMediaTypes(fastMediaTypes);
        fastConverter.setFastJsonConfig(jsonConfig);

        return fastConverter;
    }
}
